#include "Zombie.h"
#include "ZombieSwarm.h"

OpenSteer::AVGroup Zombie::_neighbors;

Zombie::Zombie(ZombieSwarm* pSwarm, Human* pHuman, ProximityDatabase& pd) :
	_pSwarm(pSwarm), _pHuman(pHuman) {

	_proximityToken = pd.allocateToken(this);
	reset();
}

void
Zombie::reset(void) {

	// TODO Jugar con estos parametros
	OpenSteer::SimpleVehicle::reset();	// reset the vehicle
	setSpeed(0.1f);											// speed along Forward direction.
	setMaxForce(0.5f);									// steering force clipped to magnitude
	setMaxSpeed(2);											// velocity is clipped to this magnitude
	clearTrailHistory();								// prevent long streaks
}

void
Zombie::update(const float currentTime, const float elapsedTime) {

	applySteeringForce(steerForZombie(elapsedTime).setYtoZero(), elapsedTime);

	annotationVelocityAcceleration ();
	recordTrailVertex (currentTime, position());
}

/*
	Esta función determina el comportamiento de los zombies. En esta versión
	es el siguiente:

		1: Perseguir al humano.
		2: Ir al centro de gravedad si se superó la distancia máxima.
		3: Vagar.
		*: Siempre se añade componente para evitar la colisión.
*/
OpenSteer::Vec3
Zombie::steerForZombie(const float elapsedTime) {

	OpenSteer::Vec3 steeringForce(0, 0, 0);

	// Evitar colisión con el resto de zombies

	const float avoidWeight = 10.0f;

	_neighbors.clear();
	_proximityToken->findNeighbors(position(), MAXRADIUS, _neighbors);

        std::cout << _neighbors.size() << std::endl;

	steeringForce =
		steerToAvoidNeighbors(MINTIMETOCOLLISION, _neighbors) * avoidWeight;

	// Perseguir al humano

	const float pursuitWeight = 20.0f;

	const float distanceToHuman = OpenSteer::Vec3::distance(
		position(), _pHuman->position());

	if (distanceToHuman < MINDISTANCE)
		return steeringForce + steerForSeek(_pHuman->position()) * pursuitWeight;

	// Moverse hacia el centro de gravedad si se alejo demasiado.

	const float distanceToSwarm = OpenSteer::Vec3::distance(
		position(), _pSwarm->swarmCenter());

	if (distanceToSwarm > MAXDISTANCE)
		return steeringForce + steerForSeek(_pSwarm->swarmCenter());

	// Vagar

	return steeringForce + steerForWander(elapsedTime);
}

void
Zombie::draw() {

	drawBasic2dCircularVehicle (*this, OpenSteer::gGreen);
	drawTrail ();
}

